package com.such.kit.database.bean;

import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import com.such.kit.database.dialect.TypeFactory;
import com.such.kit.database.support.DDLBean;
import com.such.kit.string.StringCommons;
import com.such.kit.validate.ValidateCommons;

public class DDLForeignKey extends DDLBean<List<DatabaseForeignKey>> {

	private static final long serialVersionUID = -4053328178210395552L;

	private String fkSchema;
	private String fkTableName;
	private String fkName;
	private List<String> fkColumnNames = new ArrayList<String>();
	private String referenceSchema;
	private String referenceTableName;
	private String referenceName;
	private List<String> referenceColumnNames = new ArrayList<String>();

	// 外键信息扩展
	private String changedFkName;

	public DDLForeignKey() {
		
	}

	public DDLForeignKey(List<DatabaseForeignKey> foreignKeys) {
		converter(foreignKeys);
	}

	public String getFkSchema() {
		return this.fkSchema;
	}

	public void setFkSchema(String fkSchema) {
		this.fkSchema = fkSchema;
	}

	public String getFkTableName() {
		return this.fkTableName;
	}

	public void setFkTableName(String fkTableName) {
		this.fkTableName = fkTableName;
	}

	public String getFkName() {
		return this.fkName;
	}

	public void setFkName(String fkName) {
		this.fkName = fkName;
	}

	public List<String> getFkColumnNames() {
		return this.fkColumnNames;
	}

	public void setFkColumnNames(List<String> fkColumnNames) {
		this.fkColumnNames = fkColumnNames;
	}

	public String getReferenceSchema() {
		return this.referenceSchema;
	}

	public void setReferenceSchema(String referenceSchema) {
		this.referenceSchema = referenceSchema;
	}

	public String getReferenceTableName() {
		return this.referenceTableName;
	}

	public void setReferenceTableName(String referenceTableName) {
		this.referenceTableName = referenceTableName;
	}

	public String getReferenceName() {
		return this.referenceName;
	}

	public void setReferenceName(String referenceName) {
		this.referenceName = referenceName;
	}

	public List<String> getReferenceColumnNames() {
		return this.referenceColumnNames;
	}

	public void setReferenceColumnNames(List<String> referenceColumnNames) {
		this.referenceColumnNames = referenceColumnNames;
	}

	public void addFkColumnName(String fkColumnName) {
		this.fkColumnNames.add(fkColumnName);
	}

	public void addReferenceColumnName(String referenceColumnName) {
		this.referenceColumnNames.add(referenceColumnName);
	}

	public String getChangedFkName() {
		return this.changedFkName;
	}

	public void setChangedFkName(String changedFkName) {
		this.changedFkName = changedFkName;
	}

	public void converter(List<DatabaseForeignKey> foreignKeys) {
		if (ValidateCommons.isNotEmpty(foreignKeys)) {
			boolean first = true;
			String checkKey = "";
			for (DatabaseForeignKey foreignKey : foreignKeys) {
				String fkSchema = foreignKey.getFkSchema();
				String fkTableName = foreignKey.getFkTableName();
				String fkName = foreignKey.getFkName();
				String referenceSchema = foreignKey.getPkSchema();
				String referenceTableName = foreignKey.getPkTableName();
				String referenceName = foreignKey.getPkName();
				String key = StringCommons.merger(fkSchema, fkTableName, fkName);
				if (first) {
					first = false;
					checkKey = StringCommons.merger(fkSchema, fkTableName, fkName);
					setFkSchema(fkSchema);
					setFkTableName(fkTableName);
					setFkName(fkName);
					setReferenceSchema(referenceSchema);
					setReferenceTableName(referenceTableName);
					setReferenceName(referenceName);
				}
				// 校验列是否属于一个外键
				if (key.equals(checkKey)) {
					addFkColumnName(foreignKey.getFkColumnName());
					addReferenceColumnName(foreignKey.getPkColumnName());
				}
			}
		}
	}

	public Map<String, String> buildRendererParams(Map<String, String> resourceKeyMapping, Map<String, String> ddlTemplateMapping, Map<String, String> params, TypeFactory type) {
		String fkTableName = this.fkTableName;
		if (ValidateCommons.isNotEmpty(this.fkSchema) && ValidateCommons.isNotEmpty(fkTableName)) {
			fkTableName = StringCommons.merger(this.fkSchema, ".", fkTableName);
		}
		String referenceTableName = this.referenceTableName;
		if (ValidateCommons.isNotEmpty(this.referenceSchema) && ValidateCommons.isNotEmpty(referenceTableName)) {
			referenceTableName = StringCommons.merger(this.referenceSchema, ".", referenceTableName);
		}

		Map<String, String> foreignKeyParams = new HashMap<String, String>();
		if (ValidateCommons.isNotEmpty(params)) {
			foreignKeyParams.putAll(params);
		}
		putString("fkTableName", fkTableName, foreignKeyParams, resourceKeyMapping, ddlTemplateMapping);
		putString("fkName", fkName, foreignKeyParams, resourceKeyMapping, ddlTemplateMapping);
		putList("fkColumnNames", this.fkColumnNames, foreignKeyParams, resourceKeyMapping, ddlTemplateMapping);
		putString("referenceTableName", referenceTableName, foreignKeyParams, resourceKeyMapping, ddlTemplateMapping);
		putString("referenceName", this.referenceName, foreignKeyParams, resourceKeyMapping, ddlTemplateMapping);
		putList("referenceColumnNames", this.referenceColumnNames, foreignKeyParams, resourceKeyMapping, ddlTemplateMapping);
		putString("changedFkName", this.changedFkName, foreignKeyParams, resourceKeyMapping, ddlTemplateMapping);
		return foreignKeyParams;
	}

	/**
	 * <p>方法名：grouping</p>
	 * <p>描述：根据 fkSchema、fkTableName、fkName 进行分组</p>
	 * @param foreignKeys DatabaseForeignKey
	 * @return 分组列表
	 */
	public static Map<String, List<DatabaseForeignKey>> grouping(List<DatabaseForeignKey> foreignKeys) {
		Map<String, List<DatabaseForeignKey>> foreignKeysMap = new HashMap<String, List<DatabaseForeignKey>>();
		if (ValidateCommons.isNotEmpty(foreignKeys)) {
			Collections.sort(foreignKeys);
			for (DatabaseForeignKey foreignKey : foreignKeys) {
				String fkSchema = foreignKey.getFkSchema();
				String fkTableName = foreignKey.getFkTableName();
				String fkName = foreignKey.getFkName();
				String key = StringCommons.merger(fkSchema, fkTableName, fkName);
				List<DatabaseForeignKey> tempForeignKeys = foreignKeysMap.get(key);
				if (ValidateCommons.isEmpty(tempForeignKeys)) {
					tempForeignKeys = new ArrayList<DatabaseForeignKey>();
				}
				tempForeignKeys.add(foreignKey);
				foreignKeysMap.put(key, tempForeignKeys);
			}
		}
		return foreignKeysMap;
	}

}
